package main

import (
	"fmt"
	"os"
	"runtime"
	"net/http"
)

//declare vars

var(
	// Max_num = os.Getenv("MAX_NUM")
	MaxWorker = runtime.NumCPU()
	MaxQueue=1000
)

type Serload struct{

	pri string
}

type Job  struct{
	serload Serload
}

var JobQueue chan Job

type Worker struct{
	WorkerPool chan chan Job
	JobChannel chan Job
	Quit chan bool
}


func NewWorker(workPool chan chan Job) Worker {
	return Worker{
		WorkerPool:workPool,
		JobChannel:make(chan Job),
		Quit:make(chan bool),
	}
}


func (w Worker) Start() {
	go func() {
		for{
			w.WorkerPool <- w.JobChannel
			select{
			case Job:= <-w.JobChannel:
				//excute job
				fmt.Println(job.serload.pri)
			case <- w.Quit:
				return
			}

		}
	}()
}

func (w Worker) Stop() {
	go func () {
		w.Quit <- true
	}()
}


type Dispatcher struct{
	MaxWorker int
	WorkerPool chan chan Job
	Quit bool
}


func NewDispatcher(maxWorkers int) *Dispatcher {
	pool:=make(chan chan Job, maxWorkers)
	return &Dispatcher{MaxWorker:maxWorkers,WorkerPool:pool,Quit:make(chan bool)}
}

func (d *Dispatcher) Run() {
	for i := 0; i < d.MaxWorker; i++ {
		worker:=NewWorker(d.WorkerPool)
		worker.Start()
	}
	go d.Dispatcher()
}

func (d *Dispatcher) Stop() {
	go func () {
		d.Quit <-true
	}()
}

func (d *Dispatcher) Dispatcher() {
	for{
		select{
		case job:= <- JobQueue:
			go func (job Job) {
				jobChannel:= <- d.WorkerPool
				jobChannel <- job
			}(job)
		case <- d.Quit:
			return
		}
	}
}


func entry(res http.ResponseWriter, req *http.Request) {
	//fetch job
	work:=Job{serload:Serload{pri:"Just do it"}}
	JobQueue <- work
	fmt.Fprintf(res, "hello world ...again")
}


func init() {
	runtime.GOMAXPROCS(MaxWorker)
	JobQueue = make(chan Job, MaxQueue)
	dispatcher := NewDispatcher(MaxWorker)
	dispatcher.Run()
}


func main() {
	Port:"8086"
	IsHttp:=true
	arg_num=len(os.Args)
	if 2<=arg_num{
		Port = os.Args[1]
	}
	if 3<= arg_num{
		if os.Args[2]=="true"{
			IsHttp=true
		}else{
			IsHttp=false
		}
	}

	fmt.Printf("server is http %t\n", IsHttp)
	fmt.Printf("server listens at",Port)

	http.HandlerFunc("/",entry)

	var err error
	if IsHttp{
		err = http.ListenAndServe(":"+Port,nil)
	}else{
		http.ListenAndServeTLS(":"+Port,"server.crt",nil)
	}

	if err!=nil{
		fmt.Println("Server failure ///",err)
	}

	fmt.Println("quit")
}
